package cn.sinjet.model.carsystem;

import com.amap.navi.NaviModel;
import com.mgroup.wazehelper.R;

import android.content.Context;
import android.os.Handler;
import android.util.Log;
import cn.sinjet.carassist.SinjetApplication;
import cn.sinjet.communication.bluetooth.BluetoothModel;
import cn.sinjet.entity.TireData;
import cn.sinjet.model.carassist.AppModel;
import cn.sinjet.model.carassist.SinjetService;
import cn.sinjet.utils.Data;
import cn.sinjet.viewmodel.PageDefine;
import cn.sinjet.viewmodel.ViewModel;

public class TpmsModule {
	 CarModel model;
	 static final String tag = "tpms";
	 boolean mIsInPairingPage = false;
	 boolean mIsPairing = false;
	 //all tire data
     TireData[] mTireData = new TireData[4]; 	 
     boolean mIsRecvedTireData = false;	 
     Context mContext;
     public TpmsModule(CarModel model){
    	 mContext = SinjetApplication.getInstance().getApplicationContext();
    	 String[] tireText = new String[]{"Left Front","Right Front","Left Rear","Right Rear"};
    	 int[] vIdValue = new int[]{R.id.tpms_lf_tire_pressure,R.id.tpms_rf_tire_pressure,R.id.tpms_lr_tire_pressure,R.id.tpms_rr_tire_pressure};
    	 int[] vIdTemp = new int[]{R.id.tpms_lf_temperature,R.id.tpms_rf_temperature,R.id.tpms_lr_temperature,R.id.tpms_rr_temperature};
    	 int[] vIdState = new int[]{R.id.tpms_lf_status,R.id.tpms_rf_status,R.id.tpms_lr_status,R.id.tpms_rr_status};
    	 int[] vIdPair = new int[]{R.id.tpms_lf_pair,R.id.tpms_rf_pair,R.id.tpms_lr_pair,R.id.tpms_rr_pair};
    	 for(int i=0;i<mTireData.length;i++){
    		 TireData tireData = new TireData();
    		 mTireData[i] = tireData;
             mTireData[i].tireText = tireText[i];
             mTireData[i].vIdValue = vIdValue[i];
             mTireData[i].vIdTemp = vIdTemp[i];
             mTireData[i].vIdState = vIdState[i];
             mTireData[i].vIdPair = vIdPair[i];
    	 }
     }
     
     public void onRecvTPMS(byte[] buf) {
 		// TODO Auto-generated method stub
 		int cmd = buf[1];
 		switch(cmd){
 		case 0x00:{
 			int whichWheel = Data.byteH4(buf[2]);
 			int pairState = Data.byteL4(buf[2]);
 			onPairState(whichWheel,pairState);
 		}break;
 		case 0x01:{
 	        
 		}break;
 		case 0x02:{
 			
 		}break;
 		case 0x03:{
 			
 		}break;
 		case 0x04:{
 			int tirePos = buf[2];
 			int h = (int)(buf[3]&0xF0) >>4;
 			int l= buf[3]&0x0F;
 			float tireValue = h + l/10.0f;
 			int tireTemp = 0xFF;
 			if(buf[4] != (byte)0xFF)
 			   tireTemp = (int)(buf[4]&0xFF)-40;
 			
 			byte tireStatus = buf[5];
 			Log.d(tag, "onTpms data:"+tireTemp);
 			onTireData(tirePos,tireValue,tireTemp,tireStatus);
 		}break;
 		}
 	}

     
     
 	private void onPairState(int whichWheel, int pairState) {
		// TODO Auto-generated method stub
 		Log.i(tag, "onPairState :"+whichWheel+" ,"+pairState);
		switch(pairState){
		case 0://enter pair
			mIsPairing = true;
			refreshPairingState(whichWheel);
			break;
		case 1://pair succeed
			mIsPairing = false;
			ViewModel.getIns().showToast("Pair succeed！");
			refreshCancelPairing();
			refreshPairsucceed(whichWheel);
			break;
		case 2://pair fail
			mIsPairing = false;
			ViewModel.getIns().showToast("Pair failed or time out！");
			refreshCancelPairing();
			break;
		}
	}
 	
 	void refreshPairsucceed(int which){
 		for(int i=0;i<mTireData.length;i++){
 			if(i == which){
 				ViewModel.getIns().setViewVisible(mTireData[i].vIdPair, 0);
				ViewModel.getIns().setViewVisible(mTireData[i].vIdState, 1);
				ViewModel.getIns().setViewVisible(mTireData[i].vIdTemp, 1);
				ViewModel.getIns().setViewVisible(mTireData[i].vIdValue, 1);
				break;
 			}
 		}
 	}
 	void refreshPairingState(int which){
 		for(int i=0;i<mTireData.length;i++){
 			if(i == which){
 				ViewModel.getIns().setViewProperty(mTireData[i].vIdPair,1);
 			}else{
 				ViewModel.getIns().setViewProperty(mTireData[i].vIdPair,0);
 			}
 		}
 	}
 	void refreshCancelPairing(){
 		for(TireData tireData:mTireData){
 			ViewModel.getIns().setViewProperty(tireData.vIdPair, 0);
 		}
 	}
 	
 	void onClkEnterPair(){
 		mIsInPairingPage = !mIsInPairingPage;
 		refreshPairModeUI(mIsInPairingPage);
 	}
 	
 	void refreshPairModeUI(boolean isPairing){
 		int pairTextVisible = isPairing? 1:0;
 		int valueTextVisible = isPairing?0:1;
 		if(isPairing) ViewModel.getIns().setViewProperty(R.id.tpms_enter_pair, mContext.getResources().getString(R.string.ok));
 		else ViewModel.getIns().setViewProperty(R.id.tpms_enter_pair, mContext.getResources().getString(R.string.pair));
 		
 		ViewModel.getIns().setViewVisible(R.id.pair_hint_text, pairTextVisible);
 		for(TireData tireData:mTireData){
 			ViewModel.getIns().setViewVisible(tireData.vIdPair, pairTextVisible);
 			if(!isPairing)//if cancel pairing
 			ViewModel.getIns().setViewProperty(tireData.vIdPair, 0);
 			
 			ViewModel.getIns().setViewVisible(tireData.vIdState, valueTextVisible);
 			ViewModel.getIns().setViewVisible(tireData.vIdTemp, valueTextVisible);
 			ViewModel.getIns().setViewVisible(tireData.vIdValue, valueTextVisible);
 		}
 	}
 	
 	
    void sendPairTpms(int whichWheel){
    	byte bWhich = (byte)whichWheel;
    	bWhich = (byte) ((bWhich&0x0F)<<4);
    	byte[] buf = new byte[]{0x00,bWhich};
    	packAndSendTpmsMsg(buf,buf.length);
    }
    
    void packAndSendTpmsMsg(byte[] message,int len){
    	byte[] szMsg = new byte[len + 5];
		szMsg[0] = (byte) 0xFF;
		szMsg[1] = (byte) 0x55;
		szMsg[2] = (byte) (len + 1);
		szMsg[3] = (byte) 0x04;
		System.arraycopy(message, 0, szMsg, 4, len);

		byte sum = 0;
		int s = 0;
		int i = 0;
		for (i = 2; i < len + 4; i++) {
			s += (szMsg[i] & 0xFF);
		}
		sum = (byte) (s & 0xFF);
		szMsg[len + 4] = sum;
		BluetoothModel.getInstance().sendMessage(szMsg);
    }
    
    
	private void onTireData(int tirePos, float tireValue, int tireTemp, byte tireStatus) {
 		// TODO Auto-generated method stub

		Log.d(tag, "onTireData");
		mIsRecvedTireData = true;
 		boolean bSupportPair = false;
 		if((tireStatus & 0x40) != 0)
 			bSupportPair = true;
 		updatePairButton(bSupportPair);
 		
 		if(tirePos >=0 && tirePos <=3){
 			handleTireData(mTireData[tirePos],tireValue,tireTemp,tireStatus);
 		}
 		
 	}
	
	void handleTireData(TireData tireData,float tire, int temp, int state){
		if(tireData == null) return;
		
		if(tireData.tireValue != tire){
			tireData.tireValue = tire;
			String tirePressure = String.valueOf(tire)+"BAR";
			ViewModel.getIns().setViewProperty(tireData.vIdValue,tirePressure);
		}
		if(tireData.temperature != temp){
			tireData.temperature = temp;
			String temperature = "";
	 		if(temp != 0xFF)
	 			temperature = String.valueOf(temp)+"℃";
	 		ViewModel.getIns().setViewProperty(tireData.vIdTemp, temperature);
		}
		
		if(tireData.tireState != state){
			tireData.tireState = state;
			String stateText = getErrTextByState(state);
			/*if(stateText !=null && stateText.equals("胎压正常")){
				Log.d(tag, "tire nomal set normal color");
				ViewModel.getIns().setViewProperty(tireData.vIdState, 0xFFFFFFFE);
			}*/
			ViewModel.getIns().setViewProperty(tireData.vIdState,stateText);
			
			if(stateText !=null && !stateText.equals("Normal")){
				ViewModel.getIns().setViewProperty(tireData.vIdState, 0xFFF61313);
				if(ViewModel.getIns().getCurPage() != PageDefine.PAGE_CAR_TPMS)
					ViewModel.getIns().jumpPage(PageDefine.PAGE_CAR_TPMS);
				voiceWarningTpms(tireData.tireText+stateText);
			}else{
				ViewModel.getIns().setViewProperty(tireData.vIdState, 0xFFFFFFFE);
			}
		}
	}
	
	
	String getErrTextByState(int tireStatus){
		String notifyStr = "";
 		if((tireStatus & 0x01)!=0)//慢漏
 			notifyStr += "slow leak ";
 		if((tireStatus & 0x02)!=0)//快漏
 			notifyStr += "fast leak ";
 		if((tireStatus & 0x04)!=0)//传感器低电
 			notifyStr += "battery low ";
 		if((tireStatus & 0x08)!=0)//轮胎过热
 			notifyStr += "overheating ";
 		if((tireStatus & 0x10)!=0)//
 			notifyStr += "too high ";
 		if((tireStatus & 0x20)!=0)//
 			notifyStr += "too low ";
 		//if((tireStatus & 0x40)!=0)//
 			//;//reseverd
 		if((tireStatus & 0x80)!=0)//
 			notifyStr += "disconnected ";
 		if(notifyStr.equals(""))
 			notifyStr = "Normal";
 		return notifyStr;
	}
	
	boolean mIsSupportPair = false;
	void updatePairButton(boolean bSupportPair){
//		Log.d(tag, "support paire:"+bSupportPair);
		if(mIsSupportPair != bSupportPair){
		   mIsSupportPair = bSupportPair;
		   int visible = mIsSupportPair?1:0;
		   ViewModel.getIns().setViewVisible(R.id.tpms_enter_pair, visible);
		}
	}
   
	
	
	void voiceWarningTpms(final String text){
		if(AppModel.getInstance().getSettings().mTpmsVoiceOn ==0) return;
		
		new Handler().post(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
//				TTSController.getInstance(SinjetApplication.getInstance()).playText(text);	
				NaviModel.getInstance().playText(text);
			}
		});
		
	}
	
	public void onViewClk(int id){
		  Log.d(tag, "onViewClk:"+id);
		   switch(id){
		   case R.id.car_meter_tpms_tab:
			   onClkTpmsTab();
			   break;
		    case R.id.tpms_enter_pair:
		    	onClkEnterPair();
		    	break;
			case R.id.tpms_lf_pair:
			case R.id.tpms_rf_pair:
			case R.id.tpms_lr_pair:
			case R.id.tpms_rr_pair:
				onClkPair(id);
				break;
		  }
	}
	
	void onClkPair(int id){		
		switch(id){
		case R.id.tpms_lf_pair:
			sendPairTpms(0x00);
			break;
		case R.id.tpms_rf_pair:
			sendPairTpms(0x01);
			break;
		case R.id.tpms_lr_pair:
			sendPairTpms(0x02);
			break;
		case R.id.tpms_rr_pair:
			sendPairTpms(0x03);
			break;
		}
	}
	
	private void onClkTpmsTab(){
		if(mIsRecvedTireData)
		      ViewModel.getIns().jumpPageInUIThread(PageDefine.PAGE_CAR_TPMS);
		else{
			  Context context = SinjetApplication.getInstance().getApplicationContext();
			  ViewModel.getIns().showToast(context.getResources().getString(R.string.tpms_not_found));
		}
	}
}
